{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[toc]\n",
    "\n",
    "# 什么是向量\n",
    "\n",
    "向量具有大小和方向的特性，可以表示空间中的线段、位移、速度等。向量可以用坐标形式表示，例如二维空间中的向量常表示为包含横纵坐标的有序数对。向量有几何向量、物理向量等分类，其运算规则包括加法、数乘等\n",
    "\n",
    "1. 方向性：向量可以表示方向，这是它与标量的一个重要区别。例如，在二维平面上的位移，可以表示为一个既有大小又有方向的向量\n",
    "2. 可加性：向量可以进行加法运算，两个向量相加的结果仍然是一个向量。这种运算遵循平行四边形法则或三角形法则\n",
    "3. 数乘性：标量与向量相乘时，结果仍然是一个向量。这种数乘运算可以改变向量的大小和方向\n",
    "4. 线性组合：多个向量可以组合成一个新的向量，这在机器学习和人工智能中的线性代数中非常常见\n",
    "\n",
    "# 向量的更多术语和表示法\n",
    "\n",
    "- 标量 -- 和向量相对应,一个数字\n",
    "- 代数 -- 用符号代表数,和标量的区别,向量的复合画箭头 -- $\\vec{v}$\n",
    "- 个别情况下,考虑起始点 -- $\\overrightarrow{AB}$\n",
    "- 行向量和列向量 -- 通常一个向量表示为一个列向量\n",
    "\n",
    "# 实现属于我们自己的向量\n",
    "\n",
    "```python\n",
    "class Vector:\n",
    "\n",
    "    def __init__(self, lst):\n",
    "        self._values = list(lst) #使用list()方法实现复制\n",
    "\n",
    "    def __repr__(self):\n",
    "        return f\"Vector({self._values})\"\n",
    "\n",
    "    def __str__(self):\n",
    "        return f\"({', '.join(str(e) for e in self._values)})\"\n",
    "\n",
    "    def __len__(self):\n",
    "        return len(self._values)\n",
    "\n",
    "    def __getitem__(self, index):\n",
    "        return self._values[index]\n",
    "\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    v = Vector([1, 2, 3, 4])\n",
    "    print(v)\n",
    "    print(len(v))\n",
    "    print(v[1])\n",
    "```\n",
    "\n",
    "# 向量的两个基本运算\n",
    "\n",
    "## 向量加法\n",
    "\n",
    "平行四边形的对角线\n",
    "\n",
    "A = $\\begin{pmatrix} a \\\\ b \\\\ c \\end{pmatrix}$\n",
    "\n",
    "B = $\\begin{pmatrix} c \\\\ d \\\\ e \\end{pmatrix}$\n",
    "\n",
    "A + B = $\\begin{pmatrix}a+c\\\\b+d\\\\c+e\\end{pmatrix}$\n",
    "\n",
    "```python\n",
    "def __iter__(self):\n",
    "    return self._values.__iter__()\n",
    "\n",
    "def __add__(self, other):\n",
    "    assert len(self) == len(other), \"error in adding, Length of vectors must be same\"\n",
    "    return Vector([a + b for a, b in zip(self, other)])\n",
    "```\n",
    "\n",
    "向量减法\n",
    "\n",
    "```python\n",
    "def __sub__(self, other):\n",
    "    assert len(self) == len(other), \"error in adding, Length of vectors must be same\"\n",
    "    return Vector([a - b for a, b in zip(self, other)])\n",
    "```\n",
    "\n",
    "## 数量乘法\n",
    "\n",
    "A = $\\begin{pmatrix} a \\\\ b \\\\ c \\end{pmatrix}$\n",
    "\n",
    "A * 5 = A + A + A + A + A = $\\begin{pmatrix} 5*a \\\\ 5*b \\\\ 5*c \\end{pmatrix}$\n",
    "\n",
    "```python\n",
    "def __mul__(self, k):   #\n",
    "    \"\"\"针对 vector * number\"\"\"\n",
    "    return Vector([k * e for e in self])\n",
    "\n",
    "def __rmul__(self, k):\n",
    "    \"\"\"\n",
    "    针对 number * vector\n",
    "    简写 return self * k\n",
    "    \"\"\"\n",
    "    return Vector([k * e for e in self])\n",
    "\n",
    "def __pos__(self):\n",
    "    \"\"\"带+  加号 向量\"\"\"\n",
    "    return 1 * self\n",
    "\n",
    "def __neg__(self):\n",
    "    \"\"\"带负号向量\"\"\"\n",
    "    return -1 * self\n",
    "```\n",
    "\n",
    "# 向量运算基本性质\n",
    "\n",
    "1. 交换律 -- $\\vec{u} + \\vec{v} = \\vec{v} + \\vec{u}$\n",
    "2. 结合律 -- $(\\vec{u}+\\vec{v})+\\vec{w} = \\vec{u}+(\\vec{v}+\\vec{w})$\n",
    "3. 分配率01 -- $k(\\vec{u}+\\vec{v}) = k\\vec{u}+k\\vec{v}$\n",
    "4. 分配率02 -- $(k+c)\\vec{u} = k\\vec{u}+c\\vec{u}$\n",
    "5. $k(c\\vec{u}) = kc\\vec{u}$\n",
    "6. $1\\vec{u} = \\vec{u}$\n",
    "\n",
    "# 零向量\n",
    "\n",
    "1. 长度为0的向量叫做零向量（zero vector），记作0,没有箭头\n",
    "2. 零向量与任意向量平行，即对任意向量a，都有0//a\n",
    "3. 零向量的相反向量仍是零向量\n",
    "4. 零向量与任意向量的数量积为0\n",
    "5. 设a，b是非零向量，他们的夹角是θ，...则 $a\\perp b \\Leftrightarrow a \\cdot b=0$\n",
    "6. 0=(0，0)\n",
    "\n",
    "```python\n",
    "@classmethod\n",
    "def zero(cls,dim):\n",
    "    \"\"\"返回一个dim维的零向量\"\"\"\n",
    "    return cls([0] * dim)\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 实现属于我们自己的向量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import math\n",
    "\n",
    "\n",
    "class Vector:\n",
    "\n",
    "    def __init__(self, lst):\n",
    "        self._values = list(lst)\n",
    "\n",
    "    def __len__(self):\n",
    "        return len(self._values)\n",
    "\n",
    "    def __repr__(self):\n",
    "        return f\"Vector({self._values})\"\n",
    "\n",
    "    def __str__(self):\n",
    "        return f\"[{', '.join(str(e) for e in self._values)}]\"\n",
    "\n",
    "    def __getitem__(self, index):\n",
    "        return self._values[index]\n",
    "\n",
    "    def __setitem__(self, index, v):\n",
    "        self._values[index] = v\n",
    "\n",
    "    def __iter__(self):\n",
    "        return self._values.__iter__()\n",
    "\n",
    "    def __add__(self, other):\n",
    "        assert len(self) == len(other), \\\n",
    "            \"error in adding, Length of vectors must be same\"\n",
    "        return Vector([a + b for a, b in zip(self, other)])\n",
    "\n",
    "    def __sub__(self, other):\n",
    "        assert len(self) == len(other), \\\n",
    "            \"error in adding, Length of vectors must be same\"\n",
    "        return Vector([a - b for a, b in zip(self, other)])\n",
    "\n",
    "    def __mul__(self, other):\n",
    "        return Vector([other * e for e in self._values])\n",
    "\n",
    "    def __rmul__(self, other):\n",
    "        return Vector([other * e for e in self._values])\n",
    "\n",
    "    def __truediv__(self, other):\n",
    "        return self * (1/other)\n",
    "\n",
    "    def __pos__(self):\n",
    "        return self\n",
    "\n",
    "    def __neg__(self):\n",
    "        return -1 * self\n",
    "\n",
    "    @classmethod\n",
    "    def ones(cls, n):\n",
    "        return cls([1] * n)\n",
    "\n",
    "    @classmethod\n",
    "    def zeros(cls, n):\n",
    "        return cls([1] * n)\n",
    "\n",
    "    def norm(self):\n",
    "        return math.sqrt(sum(e ** 2 for e in self._values))\n",
    "\n",
    "    def normalize(self):\n",
    "        return self / self.norm()\n",
    "\n",
    "    def dot(self, other):\n",
    "        return sum(a * b for a, b in zip(self, other))\n",
    "\n",
    "    def underlying_list(self):\n",
    "        return self._values"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
